﻿using System.Linq;
using CID.Domain.Infrastructure;
using CID.Tests.Support;
using NUnit.Framework;

namespace CID.Domain.Persistence.Tests.Infrastructure
{
    [TestFixture]
    class ParameterPersistenceTests : BasePersistenceWithDataTests
    {
        private static void AssertAreEqual(Parameter expected, Parameter actual)
        {
            Assert.AreEqual(expected.Id, actual.Id);
            Assert.AreEqual(expected.Template.Id, actual.Template.Id);
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.Description, actual.Description);
            Assert.AreEqual(expected.Type, actual.Type);
        }

        [Test]
        public void SaveNewParameter_ParameterShouldBeSaved()
        {
            var session = OpenSession();
            var newTemplate = DataProvider.CreateActivationTemplate(session, InfrastructureData.TemplateType);
            session.SaveOrUpdate(newTemplate);
            var newParameter = DataProvider.CreateParameter(session, newTemplate);
            session.SaveOrUpdate(newParameter);
            CleanSession(session);

            Assert.AreNotEqual(NotSavedId, newParameter.Id);
            session = OpenSession();
            var retrievedParameter = session.Get<Parameter>(newParameter.Id);
            AssertAreEqual(newParameter, retrievedParameter);
            CleanSession(session);
        }

        [Test]
        public void SaveModifiedParameter_ChangesShouldBeSaved()
        {
            var session = OpenSession();
            var newTemplate = DataProvider.CreateActivationTemplate(session, InfrastructureData.TemplateType);
            session.SaveOrUpdate(newTemplate);
            var newParameter = DataProvider.CreateParameter(session, newTemplate);
            session.SaveOrUpdate(newParameter);
            CleanSession(session);

            session = OpenSession();
            var modifiedParameter = session.Get<Parameter>(newParameter.Id);
            AssertAreEqual(newParameter, modifiedParameter); //Necessary to load lazy collections before the session is wiped out
            modifiedParameter.ModifyProperty(x => x.Name);
            modifiedParameter.ModifyProperty(x => x.Description);
            modifiedParameter.Type = ParameterType.Integer;
            CleanSession(session);

            session = OpenSession();
            var retrievedParameter = session.Get<Parameter>(newParameter.Id);
            AssertAreEqual(modifiedParameter, retrievedParameter);
            CleanSession(session);
        }

        [Test]
        public void DeleteParameter_ParameterShouldBeDeleted()
        {
            var session = OpenSession();
            var newTemplate = DataProvider.CreateActivationTemplate(session, InfrastructureData.TemplateType);
            session.SaveOrUpdate(newTemplate);
            var newParameter1 = DataProvider.CreateParameter(session, newTemplate, "Another Parameter");
            var newParameter2 = DataProvider.CreateParameter(session, newTemplate);
            session.SaveOrUpdate(newParameter1);
            session.SaveOrUpdate(newParameter2);
            CleanSession(session);

            session = OpenSession();
            var retrievedParameter1 = session.Get<Parameter>(newParameter1.Id);
            retrievedParameter1.Template.RemoveParameter(retrievedParameter1);
            CleanSession(session);

            session = OpenSession();
            retrievedParameter1 = session.Get<Parameter>(newParameter1.Id);
            var retrievedParameter2 = session.Get<Parameter>(newParameter2.Id);
            Assert.IsNull(retrievedParameter1);
            Assert.IsNotNull(retrievedParameter2);
            CleanSession(session);
        }
    }
}
